Repository navigation
Vendor avatar is derived via Gravatar; website_url must be http(s) - #317
Merged
Merged
Conversation
The marketplace vendor profile accepted a free-form avatar_url and served it verbatim on the public author page, so a vendor could put an arbitrary external image URL on a page other users visit. avatar_url is now always derived from the account email via Gravatar (d=identicon), the client value is ignored, and a migration NULLs non-Gravatar values already stored (the next profile save fills in the derived URL). website_url, rendered into an <a href>, now rejects non-http(s) schemes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The marketplace vendor profile accepted a free-form
avatar_urland the public author page rendered it verbatim in<img src>(src/routes/marketplace/creator.rs→GET /api/vendors/{slug}→ blog/applications/marketplace/author/[id]). A vendor could put an arbitrary external image URL on a page other users visit (tracking pixels, IP/referrer leaks, mixed-content).website_urlwas likewise rendered raw into<a href>—javascript:there is XSS.Changes
src/helpers/gravatar.rs(new):gravatar_url(email)=https://www.gravatar.com/avatar/{md5(trim(lower(email)))}?s=230&d=identicon&r=pg(same convention as the user service), plusis_gravatar_url/is_http_urlguards.md-5 = "0.10"added toCargo.toml./mine/vendor-profile:avatar_urlremoved from the request struct — the stored avatar is always derived from the authenticated user's email via Gravatar; client-supplied values are ignored (serde ignores unknown fields, old clients stay compatible).website_urlmust be http(s) or 400.20261029120000_null_non_gravatar_avatars: NULLs every non-Gravataravatar_urlalready stored (e.g. theoptimumprofile's external logo) — the next profile save fills in the derived Gravatar URL.avatar_urlignored incl. public endpoint,javascript:/data:/vbscript:website_url→ 400). 4 unit tests for the helpers.Admin vendor-profile handlers verified to carry no
avatar_url/website_urlfields — no change needed there.Verification
SQLX_OFFLINE=true cargo build— OKcargo nextest run -E 'binary(marketplace_creator_self_vendor_profile)'— 10 passedcargo test --test marketplace_public_vendor_profile— 8 passedcargo test --lib gravatar— 4 passedcargo clippy— 0 issues in changed files (27 pre-existing lints inbuild.rs/td-audit/cli//routes/from newer local clippy 1.94, identical on dev)Notes
user/app/oauth2_server/views.py).img-srcalready allowsgravatar.com; no nginx change needed.